<template>
	<div class="app-container question">
		<el-form
			:model="queryParams"
			ref="queryRef"
			:inline="true"
			v-show="showSearch"
		>
			<el-form-item label="课程" prop="courseId">
				<el-select
					v-model="queryParams.courseId"
					placeholder="请选择课程"
					clearable
				>
					<el-option
						v-for="dict in data.queryCourseList"
						:key="dict.courseId"
						:label="dict.courseName"
						:value="dict.courseId"
					/>
				</el-select>
			</el-form-item>
			<el-form-item label="难度" prop="hardLevel">
				<el-select
					v-model="queryParams.hardLevel"
					placeholder="请选择难度"
					clearable
				>
					<el-option
						v-for="dict in questionLevelQueryList"
						:key="dict.id"
						:label="dict.name"
						:value="dict.id"
					/>
				</el-select>
			</el-form-item>
			<el-form-item label="题目类型" prop="questionType">
				<el-select
					v-model="queryParams.questionType"
					placeholder="请选择难度"
					clearable
				>
					<el-option
						v-for="dict in questionTypeOptions"
						:key="dict.id"
						:label="dict.name"
						:value="dict.id"
					/>
				</el-select>
			</el-form-item>
			<!--  -->
			<el-form-item>
				<el-button type="primary" icon="Search" @click="handleQuery"
					>搜索</el-button
				>
				<el-button icon="Refresh" @click="resetQuery">重置</el-button>
			</el-form-item>
		</el-form>

		<el-row :gutter="10" class="mb8">
			<el-col :span="1.5">
				<el-button
					type="primary"
					plain
					icon="Plus"
					@click="handleAdd"
					v-hasPermi="['examination:question:add']"
					>新增</el-button
				>
			</el-col>
			<right-toolbar
				v-model:showSearch="showSearch"
				@queryTable="getList"
			></right-toolbar>
		</el-row>

		<el-main v-loading="loading">
			<div class="question__content">
				<Question
					v-if="questionList && questionList.length"
					:questionList="questionList"
					:source="1"
					@handleDelete="handleDelete"
					@handleUpdate="handleUpdate"
					@handleAdd="handleAdd"
				/>

				<el-empty v-else description="暂无数据" />
			</div>
		</el-main>

		<pagination
			v-show="total > 0"
			:total="total"
			v-model:page="queryParams.pageNum"
			v-model:limit="queryParams.pageSize"
			@pagination="getList"
		/>

		<el-dialog
			title="批量导入试题"
			v-model="importOpen"
			width="960px"
			append-to-body
			:destroy-on-close="true"
		>
			<div class="question__main">
				<el-upload
					:action="actionUrl"
					:before-upload="handleBeforeUpload"
					:limit="1"
					:on-error="handleUploadError"
					:on-success="handleUploadSuccess"
					:show-file-list="false"
					:headers="headers"
					class="question__upload"
					drag
				>
					<el-icon class="el-icon--upload"><upload-filled /></el-icon>
					<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
					<template #tip>
						<!-- <div class="el-upload__tip">
              jpg/png files with a size less than 500kb
            </div> -->
					</template>
				</el-upload>

				<div class="question__info">
					<p>文件说明:</p>
					<p>1.请下载导入模板，根据模板提示内容进行填写;</p>
					<p>2.填写模板中所有提示必填项后，将文档进行上传;</p>
					<p>3.只支持Excel文件，文件不能超过1000行;</p>
					<p>4.上传的文件必须先关闭，再上传。</p>
					<p>5.导入数据时请将模板文件中的样例数据删除。</p>
				</div>
			</div>

			<template #footer>
				<div
					style="
						display: flex;
						align-items: center;
						justify-content: space-between;
					"
				>
					<div>
						<!-- <el-button type="primary" @click="submitForm">试题导入</el-button> -->
						<el-button type="primary" @click="handleDownload"
							>模版下载</el-button
						>
					</div>
				</div>
			</template>
		</el-dialog>

		<!-- 添加或修改题库管理对话框 -->
		<el-dialog
			:title="title"
			v-model="open"
			width="960px"
			append-to-body
			:destroy-on-close="true"
		>
			<div class="question__form">
				<div class="question__form-left">
					<div class="question__form-title-wrapper">
						<span class="question__form-symbol">*</span>
						<span class="question__form-title">题目类型</span>
					</div>

					<div class="question__form-select-wrapper">
						<div
							v-for="(name, index) in questionTypeMap"
							:key="index"
							@click="changeType(index)"
							:class="{
								'question__form-select-tag-active':
									`${form.questionType}` === `${index}`,
							}"
							class="question__form-select-tag"
						>
							<img
								class="question__form-select-icon"
								:src="getImageUrl(false, index)"
							/>
							<span>{{ name }}</span>
						</div>
					</div>

					<div
						class="question__form-title-wrapper question__form-title-wrapper-border"
					>
						<span class="question__form-symbol">*</span>
						<span class="question__form-title">难易程度</span>
					</div>

					<div class="question__form-select-wrapper">
						<div
							v-for="(name, index) in questionLevelMap"
							@click="changeLevel(index)"
							:key="index"
							:class="{
								'question__form-select-tag-active':
									`${form.hardLevel}` === `${index}`,
							}"
							class="question__form-select-tag"
						>
							<img
								class="question__form-select-icon"
								:src="getImageUrl(true, index)"
							/>
							<!-- :src="`../assets/question_${index}.png`" -->
							<span>{{ name }}</span>
						</div>
					</div>
				</div>
				<div class="question__form-right">
					<p class="question__form-right-title">{{ getQuestionType(form) }}</p>
					<el-form
						label-width="80px"
						ref="questionRef"
						:model="form"
						:rules="rules"
					>
						<el-form-item label="标题" prop="questionTitle">
							<el-input
								v-model="form.questionTitle"
								:rows="2"
								type="textarea"
								placeholder="请输入课程标题"
							/>
						</el-form-item>
						<el-form-item label="答案" v-show="showAnswerConfig">
							<AnswerForm
								ref="AnswerFormRef"
								:list="data.form.questionAnswerList"
								:questionType="data.form.questionType"
								:form="data.form"
							/>

							<div
								v-if="data.form.questionType !== '3'"
								class="question__button"
								@click="addQuestionItem()"
							>
								<el-button :icon="Plus">添加选项</el-button>
							</div>
						</el-form-item>
						<el-form-item label="课程" prop="courseId">
							<el-select
								v-model="form.courseId"
								placeholder="请选择课程"
								clearable
								style="width: 300px"
							>
								<el-option
									v-for="dict in data.courseList"
									:key="dict.courseId"
									:label="dict.courseName"
									:value="dict.courseId"
								/>
							</el-select>
						</el-form-item>
					</el-form>
				</div>
			</div>
			<template #footer>
				<div
					class="dialog-footer"
					style="
						display: flex;
						align-items: center;
						justify-content: space-between;
					"
				>
					<div>
						<el-button
							type="primary"
							@click="handleImport"
							v-hasPermi="['examination:question:import']"
							>批量录入</el-button
						>
					</div>

					<div>
						<el-button type="primary" @click="submitForm">确 定</el-button>
						<el-button @click="cancel">取 消</el-button>
					</div>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup name="Question">
import { getToken } from "@/utils/auth";
import { Plus } from "@element-plus/icons-vue";

import {
	addQuestion,
	delQuestion,
	getQuestion,
	listQuestion,
	queryCourseList,
	updateQuestion,
} from "@/api/examination/question";

import Question from "@/components/Question";
import AnswerForm from "./components/AnswerForm";

import {
	question1,
	question2,
	question3,
	questionType1,
	questionType2,
	questionType3,
} from "../assets/images";

import { computed } from "vue";
const { proxy } = getCurrentInstance();

const questionList = ref([]);
const open = ref(false);
const importOpen = ref(false);

const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const headers = ref({ Authorization: "Bearer " + getToken() });

const actionUrl = `${
	import.meta.env.VITE_APP_BASE_API
}/examination/question/importData`;

const validateQuestionAnswer = () => {};

const data = reactive({
	courseList: [],
	queryCourseList: [],
	form: {
		questionId: null,
		courseId: null,
		questionTitle: null,
		questionTitleEnclosure: null,
		questionAnswers: null,
		rightAnswers: null,
		createBy: null,
		createTime: null,
		updateBy: null,
		updateTime: null,
		deleted: null,
		hardLevel: 1,
		questionType: 1,
		questionAnswerList: [],
	},
	images: {
		question1,
		question2,
		question3,
		questionType1,
		questionType2,
		questionType3,
	},
	queryParams: {
		pageNum: 1,
		pageSize: 10,
		courseId: null,
		questionType: null,
		hardLevel: null,
		questionTitle: null,
		questionTitleEnclosure: null,
		questionAnswers: null,
		rightAnswers: null,
		deleted: null,
		year: null,
	},
	copyQuestionAnswerList: [],
	rules: {
		questionAnswerList: [
			{ required: true, validator: validateQuestionAnswer, trigger: "change" },
		],
		questionTitle: [
			{ required: true, message: "请输入题目标题", trigger: "blur" },
		],
		courseId: [{ required: true, message: "请选择课程", trigger: "change" }],
	},
});
const { queryParams, form, rules } = toRefs(data);

const questionTypeMap = {
	1: "单选题",
	2: "多选题",
	3: "判断题",
	4: "填空题",
	5: "程序题",
	6: "简答题",
};
const questionTypeOptions = [
	{
		id: 1,
		name: "单选题",
	},
	{
		id: 2,
		name: "多选题",
	},
	{
		id: 3,
		name: "判断题",
	},

	{
		id: 4,
		name: "填空题",
	},
	{
		id: 5,
		name: "程序题",
	},
	{
		id: 6,
		name: "简答题",
	},
];
const questionLevelMap = {
	1: "简单",
	2: "中等",
	3: "困难",
};

// <!-- 题型;题目类型；1-单选，2-多选，3-判断;关联dict表中的code列，dict_key为question_type题目类型；1-单选，2-多选，3-判断; -->
const getQuestionType = (row) => {
	return questionTypeMap[row.questionType];
};

const questionLevelQueryList = ref([
	{
		name: "全部",
		id: null,
	},
	{
		name: "简单",
		id: 1,
	},
	{
		name: "中等",
		id: 2,
	},
	{
		name: "困难",
		id: 3,
	},
]);

const getImageUrl = (isLevel = true, index) => {
	if (isLevel) {
		return data.images[`question${index}`];
	}

	return data.images[`questionType${index}`];
};

const changeLevel = (level) => {
	data.form.hardLevel = level;
};

const AnswerFormRef = ref(null);

const changeType = (type) => {
	data.form.questionType = type;
	if (type === "1" || type === "2" || type === "3") {
		AnswerFormRef.value.changeType(Number(type));
	}
};
const showAnswerConfig = computed(() => {
	if (
		data.form.questionType === "1" ||
		data.form.questionType === "2" ||
		data.form.questionType === "3"
	) {
		return true;
	} else {
		return false;
	}
});
const addQuestionItem = () => {
	AnswerFormRef.value.addItem();
};

/** 查询题库管理列表 */
function getList() {
	loading.value = true;
	listQuestion(queryParams.value).then((response) => {
		questionList.value = response.rows;
		total.value = response.total;

		setTimeout(() => {
			loading.value = false;
		});
	});
}

function handleDownload() {
	proxy.download(
		"/examination/question/export",
		{},
		`examinationSub_template_${new Date().getTime()}.xlsx`
	);
}

function handleImport() {
	open.value = false;
	importOpen.value = true;
}

// 上传成功回调
function handleUploadSuccess(res, file) {
	if (res.code === 200) {
		getList();
		proxy.$modal.msgSuccess(`导入成功`);
		importOpen.value = false;
		return;
	}

	proxy.$modal.msgError(res.msg || "导入失败");
}

function handleExceed() {
	proxy.$modal.msgError(`上传文件数量不能超过 1 个!`);
}

// 上传失败
function handleUploadError(err) {
	proxy.$modal.msgError("上传文件失败");
}

// 上传前校检格式和大小
function handleBeforeUpload(file) {
	const fileType = ["xlsx", "xls"];
	const fileSize = 10;
	if (fileType.length) {
		const fileName = file.name.split(".");
		const fileExt = fileName[fileName.length - 1];
		const isTypeOk = fileType.indexOf(fileExt) >= 0;
		if (!isTypeOk) {
			proxy.$modal.msgError(
				`文件格式不正确, 请上传${fileType.join("/")}格式文件!`
			);
			return false;
		}
	}
	// 校检文件大小
	if (fileSize) {
		const isLt = file.size / 1024 / 1024 < fileSize;
		if (!isLt) {
			proxy.$modal.msgError(`上传文件大小不能超过 ${fileSize} MB!`);
			return false;
		}
	}
	return true;
}

// 取消按钮
function cancel() {
	open.value = false;
	reset();
}

// 表单重置
function reset() {
	form.value = {
		questionId: null,
		courseId: null,
		questionTitle: null,
		questionTitleEnclosure: null,
		questionAnswers: null,
		rightAnswers: null,
		createBy: null,
		createTime: null,
		updateBy: null,
		updateTime: null,
		deleted: null,
		hardLevel: 1,
		questionType: "1",
		questionAnswerList: [],
	};

	proxy.resetForm("questionRef");
}

/** 搜索按钮操作 */
function handleQuery() {
	queryParams.value.pageNum = 1;
	getList();
}

/** 重置按钮操作 */
function resetQuery() {
	proxy.resetForm("queryRef");
	handleQuery();
}

/** 新增按钮操作 */
function handleAdd() {
	reset();
	open.value = true;
	title.value = "添加题库管理";
}

/** 修改按钮操作 */
function handleUpdate(row) {
	reset();
	const _questionId = row.questionId || ids.value;
	getQuestion(_questionId).then((response) => {
		form.value = response.data;
		open.value = true;
		title.value = "修改题库管理";
	});
}

function checkForm() {
	const questionAnswerList = data.form.questionAnswerList;

	if (showAnswerConfig.value && !questionAnswerList) {
		proxy.$modal.msgError("请填写答案");
		return false;
	} else {
		return true;
	}
}

/** 提交按钮 */
function submitForm() {
	const questionAnswerList = AnswerFormRef.value.getQuestionAnswerList();

	const rowQuestionAnswer = questionAnswerList.filter((row) => row.rightState);

	if (rowQuestionAnswer && rowQuestionAnswer.length) {
		if (`${data.form.questionType}` === "1") {
			data.form.rightAnswers = JSON.stringify([
				rowQuestionAnswer[0].optionLabel,
			]);
		}
		if (`${data.form.questionType}` === "2") {
			data.form.rightAnswers = JSON.stringify(
				rowQuestionAnswer.map((row) => row.optionLabel)
			);
		}
		if (`${data.form.questionType}` === "3") {
			data.form.rightAnswers = JSON.stringify([rowQuestionAnswer[0].content]);
		}
	}
	if (showAnswerConfig.value) {
		data.form.questionAnswerList = questionAnswerList;
	}

	if (!checkForm()) return;

	proxy.$refs["questionRef"].validate((valid) => {
		if (valid) {
			if (form.value.questionId != null) {
				updateQuestion(form.value).then((response) => {
					proxy.$modal.msgSuccess("修改成功");
					open.value = false;
					getList();
				});
			} else {
				addQuestion(form.value).then((response) => {
					proxy.$modal.msgSuccess("新增成功");
					open.value = false;
					getList();
				});
			}
		}
	});
}

/** 删除按钮操作 */
function handleDelete(row) {
	const _questionIds = row.questionId || ids.value;
	proxy.$modal
		.confirm("是否确认删除该数据项吗？")
		.then(function () {
			return delQuestion(_questionIds);
		})
		.then(() => {
			getList();
			proxy.$modal.msgSuccess("删除成功");
		})
		.catch(() => {});
}

/** 导出按钮操作 */
function handleExport() {
	proxy.download(
		"system/question/export",
		{
			...queryParams.value,
		},
		`question_${new Date().getTime()}.xlsx`
	);
}

function getCourse() {
	queryCourseList({}).then((response) => {
		console.log("🚀 ~ getCourse ~ response:", response);
		if (response.code === 200 && response.rows.length) {
			data.queryCourseList = response.rows;
			data.courseList = response.rows;
		}
	});
}

async function init() {
	await Promise.all([getList(), getCourse()]);
}
init();
</script>

<style lang="scss" scoped>
:deep .el-dialog__body {
	padding: 0;
}

.question__content .el-card {
	margin-top: 16px;
}

.question {
	&__upload {
		width: 378px;
		height: 175px;
		margin: 0 auto;
	}

	.el-main {
		width: 100%;
		height: 100%;
		box-sizing: border-box;
		overflow: hidden;
		padding: 0 !important;
	}

	.el-form--inline .el-form-item {
		margin-right: 18px;
	}
}

.question__content .el-card :deep .el-card__body {
	display: flex;
	flex-direction: row;
	align-items: center;
}

.question {
	&__info {
		margin-top: 36px;
		color: #222;
		padding-left: 8px;
	}

	&__left {
		flex: 1;
		padding-right: 10px;
	}

	&__right {
		width: 130px;
	}

	&__title {
		font-size: 16px;
		font-family: Microsoft YaHei;
		font-weight: 400;
		line-height: 56px;
		color: #606266;
		line-height: 25px;
	}

	&__title-active {
		color: #409eff;
		margin-right: 4px;
	}

	&__select {
		color: #666;
		margin-top: 10px;
	}

	&__tags {
		align-items: center;
		margin-top: 14px;
	}

	&__tag {
		display: inline-block;
		padding: 3px 12px;
		border-radius: 8px;
		margin-right: 8px;
		font-size: 5px;
	}

	&__tag-blue {
		background-color: rgba(41, 114, 250, 0.1);
		color: #2972fa;
	}

	&__tag-green {
		background-color: rgba(30, 168, 48, 0.1);
		color: #1ea830;
	}

	&__form {
		display: flex;
		flex-direction: row;
		border-top: 1px solid #e5e8ec;
		border-bottom: 1px solid #e5e8ec;
	}

	&__form-left {
		width: 240px;
		border-right: 10px solid #f2f3f5;
		padding-bottom: 100px;
	}

	&__form-right-title {
		font-size: 14px;
		font-family: Microsoft YaHei;
		color: #303133;
		border-left: 5px solid #409eff;
		padding-left: 7px;
		margin-left: 80px;
		margin-bottom: 12px;
		font-weight: bold;
	}

	&__form-right {
		flex: 1;
		padding-bottom: 100px;
		padding-top: 8px;
	}

	&__form-title-wrapper {
		display: flex;
		align-items: center;
		flex-direction: row;
		height: 62px;
		line-height: 62px;
		width: 100%;
		padding: 0 22px;
		border-bottom: 1px solid #e5e8ec;
	}

	&__form-title-wrapper-border {
		border-top: 1px solid #e5e8ec;
		margin-top: 25px;
	}

	&__form-symbol {
		color: red;
		font-size: 14px;
	}

	&__form-title {
		color: #303133;
		font-size: 14px;
		font-weight: bold;
		font-family: Microsoft YaHei;
		font-weight: 400;
	}

	&__form-select-wrapper {
		display: flex;
		align-items: center;
		flex-direction: row;
		flex-wrap: wrap;
		margin-top: 16px;
	}

	&__form-select-tag {
		box-sizing: border-box;
		display: flex;
		align-items: center;
		flex-direction: row;
		width: 98px;
		height: 34px;
		border-radius: 3px;
		margin: 0 10px 10px 0;
		font-size: 12px;
		font-family: Microsoft YaHei;
		font-weight: 400;
		line-height: 34px;
		color: #606266;
		background: #ffffff;
		border: 1px solid #e5e7eb;
		text-align: center;
		cursor: pointer;
		padding-left: 11px;
	}

	&__form-select-tag-active {
		background: rgba(64, 158, 255, 0.1);
		border: 1px solid #409eff;
		color: #409eff;
	}

	&__form-select-icon {
		width: 12px;
		height: 12px;
		margin-right: 6px;
	}

	&__button {
		margin-top: 12px;
	}
}
</style>
